package com.aixin.csopequity.service;

import com.aixin.common.exception.CustomException;
import com.aixin.common.utils.StringUtils;
import com.aixin.csopequity.domain.ConfigEquity;
import com.aixin.csopequity.domain.EquityLevelDef;
import com.aixin.csopequity.domain.ServiceDefDomain;
import com.aixin.csopequity.domain.ServiceLevelDef;
import com.aixin.csopequity.mapper.EquityMapper;
import com.aixin.csopequity.model.*;
import com.aixin.csopequity.repository.EquityLevelRepository;
import com.aixin.csopequity.repository.EquityRepository;
import com.aixin.csopequity.repository.ServiceDefEquityRepository;
import com.aixin.csopequity.repository.ServiceLevelDefRepository;
import com.aixin.csopequity.service.EquityService;
import com.aixin.csopequity.utils.Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.time.Instant;
import java.util.*;


@Service
public class EquityService {

    @Autowired
    EquityLevelRepository equityLevelRepository;
    @Autowired
    EquityRepository equityRepository;
    @Autowired
    ServiceLevelDefRepository serviceLevelDefRepository;
    @Autowired
    ServiceDefEquityRepository serviceDefEquityRepository;

    @Autowired
    EquityMapper equityMapper;

    @Transactional
    public void saveChangedEquity(EquityLevelService changedEquity) {
        ConfigEquity equity = equityRepository.findByEquityID(changedEquity.getEquityID()).orElseThrow(() -> new CustomException("权益不存在", 500));
        // 权益数据
        equity.setUpdateTime(Instant.now());
        equity.setEquityName(changedEquity.getEquityName());
        equity.setEquityStatus(changedEquity.getEquityStatus());
        equity.setEquityType(changedEquity.getEquityType());
        equity.setRemark(changedEquity.getRemark());
        equityRepository.save(equity);

        // 先删除全部权益级别服务数据
        serviceLevelDefRepository.deleteAllByEquityID(equity.getEquityID());

        // 权益等级数据
        List<EquityLevelDef> savedEquityLevel = equityLevelRepository.getEquityLevel(equity.getEquityID());
        for (EquityLevelModel el : changedEquity.getEquityLevelDef()) {
            if (StringUtils.isEmpty(el.getEquityLevelID())) {
                // 新增等级
                EquityLevelDef eld = EquityLevelDef.builder()
                        .equityID(changedEquity.getEquityID())
                        .equityName(changedEquity.getEquityName())
                        .equityLevel(el.getEquityLevel())
                        .equityLevelID(Util.getUUID())
                        .equityLevelName(el.getEquityLevelName())
                        .equityType(changedEquity.getEquityType())
                        .equityLevelRemarks(el.getEquityLevelRemarks()).build();
                equityLevelRepository.save(eld);
            } else {
                // 修改等级
                // 在以保存的等级列表中去掉更新的数据（剩下的数据为删除数据，执行delete)
                EquityLevelDef eld = null;
                if (!StringUtils.isEmpty(el.getEquityLevelID())) {
                    Optional<EquityLevelDef> savedLevel = savedEquityLevel.stream()
                            .filter(sel -> sel.getEquityLevelID().equals(el.getEquityLevelID()))
                            .findAny();
                    if (!savedLevel.isPresent()) {
                        throw new CustomException("权益级别数据错误，请刷新页面重试", 500);
                    }
                    savedEquityLevel.remove(savedLevel.get());
                    eld = savedLevel.get();
                } else {
                    eld = new EquityLevelDef();
                    eld.setEquityLevelID(Util.getUUID());
                }
                eld.setEquityLevel(el.getEquityLevel());
                eld.setEquityLevelName(el.getEquityLevelName());
                eld.setEquityLevelRemarks(el.getEquityLevelRemarks());
                equityLevelRepository.save(eld);
            }

            // 保存权益等级 - 服务数据

            for (ServiceLevelModel service : el.getServiceLevelDef()) {
                ServiceLevelDef serviceLevelDef = ServiceLevelDef.builder()
                    .UUID(Util.getUUID())
                    .equityID(equity.getEquityID())
                    .equityLevelID(el.getEquityLevelID())
                    .serviceID(service.getServiceID())
                    .serviceName(service.getServiceName()).build();
                serviceDefEquityRepository.findByServiceID(service.getServiceID())
                        .ifPresent(s -> serviceLevelDef.setServiceName(s.getServiceName()));
                serviceLevelDefRepository.save(serviceLevelDef);
            };
        };
        savedEquityLevel.forEach(el -> equityLevelRepository.deleteByEquityLevelID(el.getEquityLevelID()));
    }

    @Transactional
    public void deleteOneEquity(String equityID) {
        // 先检查权益是否存在
        ConfigEquity equity = equityRepository.findByEquityID(equityID).orElseThrow(() -> new CustomException("该权益不存在", 404));
        // 删除所有的权益等级-服务
        serviceLevelDefRepository.deleteAllByEquityID(equityID);
        // 删除所有权益等级
        equityLevelRepository.deleteAllByEquityID(equityID);
        // 删除权益
        equityRepository.deleteByEquityID(equityID);
    }

    @Transactional
    public SystemReturn saveEquity(EquityLevelService equityLevelService) {
        ConfigEquity configEquity = new ConfigEquity();
        configEquity.setEquityID(Util.getUUID());
        configEquity.setCreateTime(Instant.now());
        configEquity.setEquityName(equityLevelService.getEquityName());
        configEquity.setEquityType(equityLevelService.getEquityType());
        configEquity.setEquityStatus(equityLevelService.getEquityStatus());
        configEquity.setRemark(equityLevelService.getRemark());
        List<EquityLevelDef> equityLevelDefs = new ArrayList<>();
        List<ServiceLevelDef> serviceLevelDefs = new ArrayList<>();
        for (EquityLevelModel equityLevelModel : equityLevelService.getEquityLevelDef()) {
            EquityLevelDef equityLevelDef = new EquityLevelDef();
            equityLevelDef.setEquityLevelID(Util.getUUID());
            equityLevelDef.setEquityID(configEquity.getEquityID());
            equityLevelDef.setEquityName(configEquity.getEquityName());
            equityLevelDef.setEquityType(configEquity.getEquityType());
            equityLevelDef.setEquityLevel(equityLevelModel.getEquityLevel());
            equityLevelDef.setEquityLevelName(equityLevelModel.getEquityLevelName());
            equityLevelDef.setEquityLevelRemarks(equityLevelModel.getEquityLevelRemarks());
            for (ServiceLevelModel serviceLevelModel : equityLevelModel.getServiceLevelDef()) {
                ServiceLevelDef serviceLevelDef = new ServiceLevelDef();
                serviceLevelDef.setUUID(Util.getUUID());
                serviceLevelDef.setEquityID(configEquity.getEquityID());
                serviceLevelDef.setEquityLevelID(equityLevelDef.getEquityLevelID());
                serviceLevelDef.setServiceID(serviceLevelModel.getServiceID());
                serviceLevelDef.setServiceName(serviceLevelModel.getServiceName());
                serviceLevelDefs.add(serviceLevelDef);
            }
            equityLevelDefs.add(equityLevelDef);
        }
        equityRepository.save(configEquity);
        equityLevelRepository.saveAll(equityLevelDefs);
        serviceLevelDefRepository.saveAll(serviceLevelDefs);
        return SystemReturn.getSystemTrueReturn();
    }


    public Page<ConfigEquity> getEquity(ConfigEquityModel configEquityModel, int pageNum, int pageSize) {

        if ("".equals(configEquityModel.getEquityID())) {
            configEquityModel.setEquityID(null);
        }

        if ("".equals(configEquityModel.getEquityLevelID())) {
            configEquityModel.setEquityLevelID(null);
        }

        if ("".equals(configEquityModel.getServiceID())) {
            configEquityModel.setServiceID(null);
        }

        Pageable pageRequest = PageRequest.of(pageNum - 1, pageSize);
        Page<ConfigEquity> pageList = equityRepository.getEquity(configEquityModel.getEquityID(),
                configEquityModel.getEquityType(),
                configEquityModel.getEquityLevelID(),
                configEquityModel.getServiceID(), pageRequest);

        return pageList;
    }


    @Transactional
    public SystemReturn updateEquity(ConfigEquity configEquity) {
        equityRepository.updateEquity(configEquity.getEquityID(),
                configEquity.getEquityType(),
                configEquity.getEquityName(),
                configEquity.getEquityStatus(),
                configEquity.getRemark(),
                Util.getNowDate());
        return SystemReturn.getSystemTrueReturn();
    }


    @Transactional
    public SystemReturn updateEquityLevel(EquityLevelDef equityLevelDef) {
        equityLevelRepository.updateEquityLevel(
                equityLevelDef.getEquityLevelName(),
                equityLevelDef.getEquityLevelRemarks(),
                equityLevelDef.getEquityLevel(),
                equityLevelDef.getEquityLevelID());
        return SystemReturn.getSystemTrueReturn();
    }


    public Optional<ConfigEquity> getEquityByID(String equityID) {
        return equityRepository.findByEquityID(equityID);
    }


    public List<EquityLevelDef> getEquityLevel(String equityID) {
        return equityLevelRepository.getEquityLevel(equityID);
    }


    @Transactional
    public SystemReturn deleteEquity(String equityID) {
        if (!queryCostomer(equityID, null, null)) {
            SystemReturn systemReturn = new SystemReturn("FALSE", "此权益有用户请勿删除!");
            return systemReturn;
        }
        ServiceLevelDef serviceLevelDef = new ServiceLevelDef();
        serviceLevelDef.setEquityID(equityID);
        equityMapper.deleteServiceLevelDef(serviceLevelDef);
        equityMapper.deleteEquityLevel(serviceLevelDef);
        System.out.println(equityID);
        int num = equityMapper.deleteEquity(equityID);
        System.out.println(num);
        return SystemReturn.getSystemTrueReturn();
    }


    @Transactional
    public SystemReturn deleteEquiytLevel(String equityID, String equityLevelID) {
        if (!queryCostomer(equityID, equityLevelID, null)) {
            SystemReturn systemReturn = new SystemReturn("FALSE", "此等级有用户请勿删除!");
            return systemReturn;
        }
        ServiceLevelDef serviceLevelDef = new ServiceLevelDef();
        serviceLevelDef.setEquityID(equityID);
        serviceLevelDef.setEquityLevelID(equityLevelID);
        equityMapper.deleteServiceLevelDef(serviceLevelDef);
        equityMapper.deleteEquityLevel(serviceLevelDef);
        return SystemReturn.getSystemTrueReturn();
    }


    public SystemReturn deleteLevelService(String equityID, String equityLevelID, String serviceID) {
        if (!queryCostomer(equityID, equityLevelID, serviceID)) {
            SystemReturn systemReturn = new SystemReturn("FALSE", "此服务有用户请勿删除!");
            return systemReturn;
        }
        ServiceLevelDef serviceLevelDef = new ServiceLevelDef();
        serviceLevelDef.setEquityID(equityID);
        serviceLevelDef.setEquityLevelID(equityLevelID);
        serviceLevelDef.setServiceID(serviceID);
        int num = equityMapper.deleteServiceLevelDef(serviceLevelDef);
        System.out.println(num);
        return SystemReturn.getSystemTrueReturn();
    }


    public SystemReturn saveLevelService(LevelServiceModel insertLevelService) {

        ServiceLevelDef serviceLevelDef = new ServiceLevelDef();
        serviceLevelDef.setUUID(Util.getUUID());
        serviceLevelDef.setEquityID(insertLevelService.getEquityID());
        serviceLevelDef.setEquityLevelID(insertLevelService.getEquityLevelID());
        serviceLevelDef.setServiceID(insertLevelService.getServiceID());
        serviceLevelDef.setServiceName(insertLevelService.getServiceName());
        serviceLevelDefRepository.save(serviceLevelDef);
        return SystemReturn.getSystemTrueReturn();
    }


    public SystemReturn saveEquityLevel(InsertEquityLevel insertEquityLevel) {

        EquityLevelDef equityLevelDef = new EquityLevelDef();
        equityLevelDef.setEquityLevelID(Util.getUUID());
        equityLevelDef.setEquityID(insertEquityLevel.getEquityID());
        equityLevelDef.setEquityName(insertEquityLevel.getEquityName());
        equityLevelDef.setEquityType(insertEquityLevel.getEquityType());
        equityLevelDef.setEquityLevel(insertEquityLevel.getEquityLevel());
        equityLevelDef.setEquityLevelName(insertEquityLevel.getEquityLevelName());
        equityLevelDef.setEquityLevelRemarks(insertEquityLevel.getEquityLevelRemarks());
        equityLevelRepository.save(equityLevelDef);
        return SystemReturn.getSystemTrueReturn();
    }

    public boolean queryCostomer(String equityID, String equityLevelID, String serviceID) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("equityID", equityID);
        map.put("equityLevelID", equityLevelID);
        map.put("serviceID", serviceID);
        int num = equityMapper.queryService(map);
        if (num < 1) {
            return true;
        }
        return false;
    }
}
